# =================================================================
# 多阶段构建的 Dockerfile - 详细解释版
# 作用：将Java Spring Boot项目打包成Docker镜像
# =================================================================

# ========================================
# 第一阶段：构建阶段（Build Stage）
# ========================================
# 从Maven官方镜像开始，包含JDK 17和Maven
FROM maven:3.8.7-openjdk-17 AS builder

# 设置工作目录 - 就像进入一个专门的文件夹工作
WORKDIR /app

# 复制Maven配置文件 - 先复制依赖配置文件
# 作用：利用Docker层缓存，如果pom.xml没变就不重新下载依赖
COPY pom.xml .

# 下载并缓存所有依赖 - 这一步会下载项目需要的所有Java包
RUN mvn dependency:go-offline -B

# 复制源代码 - 把Java代码文件复制到容器里
COPY src/ ./src/

# 编译并打包项目 - 执行maven构建，生成可执行的JAR文件
# -B: 批处理模式
# -DskipTests: 跳过测试
# -q: 静默模式，只显示错误
RUN mvn clean package -B -DskipTests

# ========================================
# 第二阶段：运行时阶段（Runtime Stage）
# ========================================
# 从OpenJDK 17基础镜像开始（轻量版）
FROM openjdk:17-jdk-slim

# 设置时区 - 确保时间显示正确，避免时差问题
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 创建非root用户 - 安全最佳实践，避免用root权限运行应用
RUN groupadd -r appuser && useradd -r -g appuser appuser

# 设置工作目录 - 应用存放的位置
WORKDIR /app

# 设置JVM参数优化 - 优化Java虚拟机性能
ENV JAVA_OPTS="-Xmx1024m -Xms512m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+DisableExplicitGC -Djava.security.egd=file:/dev/./urandom"

# 从构建阶段复制生成的JAR文件 - 这是最终要运行的应用程序
COPY --from=builder /app/target/*.jar app.jar

# 暴露端口 - 告诉Docker容器要开放哪个端口给外部访问
# Spring Boot默认使用8080端口
EXPOSE 8081

# 切换到非root用户 - 提高安全性
USER appuser

# 启动命令 - Docker容器启动时执行的命令
# ENTRYPOINT: 容器启动时必执行的命令
# CMD: 可以被docker run时覆盖的默认参数
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

# ========================================
# 额外优化（可选添加）
# ========================================

# 如果需要健康检查，可以添加：
# HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
#   CMD curl -f http://localhost:8081/actuator/health || exit 1

# 如果需要挂载日志目录：
# VOLUME ["/app/logs"]

# 如果需要挂载配置文件：
# VOLUME ["/app/config"]

# 如果需要设置环境变量：
# ENV SPRING_PROFILES_ACTIVE=docker

# 如果需要启动前执行初始化脚本：
# COPY --chown=appuser:appuser init.sh /app/
# RUN chmod +x /app/init.sh
# ENTRYPOINT ["/app/init.sh", "java", "$JAVA_OPTS", "-jar", "app.jar"]